﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Newtonsoft.Json;

namespace MapEditorSDG
{
    enum AllEventTypes { none, tsunami };

    class GridHandler: Panel
    {
        //Name of all events.
        public const string EVENTNAME_NONE = "none";
        public const string EVENTNAME_TSUNAMI = "tsunami";
        public const string EVENTNAME_SEAMONSTER = "sea_monster";

        //Both, width and height, are calculated by their size in cases.
        public const int PANEL_DEFAULT_CELL_WIDTH = 1;
        public const int PANEL_DEFAULT_CELL_HEIGHT = 1;
        public const int MAX_ROW = 100;
        public const int MAX_COLUMN = 100;

        private int mapEvent;
        private GameCell[,] gameCells;

        private string imgSrc;

        public GridHandler(int _x, int _y, int _row, int _column, Control _parent, GameCell[,] _cells = null)
        {
            imgSrc = "";
            mapEvent = (int) AllEventTypes.none;

            //Prevent user to create a map unusually huge.
            if (_row > MAX_ROW)
                _row = MAX_ROW;
            if (_column > MAX_COLUMN)
                _column = MAX_COLUMN;

            this.Parent = _parent;

            this.SetBounds(_x, _y, _column * GameCell.CELL_WIDTH, (int) _row * GameCell.CELL_HEIGHT + GameCell.CELL_HEIGHT/2);

            if (_cells == null)
            {
                gameCells = new GameCell[_column, _row];

                for (int i = 0; i < _row; i++)
                    for (int j = 0; j < _column; j++)
                    {
                        gameCells[j, i] = new GameCell(this, j, i);
                        gameCells[j, i].ChooseColor();
                    }
            }
            else
            {
                gameCells = _cells;

                for (int i = 0; i < _row; i++)
                    for (int j = 0; j < _column; j++)
                    {
                        gameCells[j, i].Cell.Parent = this;
                        gameCells[j, i].ChooseColor();
                    }
            }
        }

        public void resize(int _row, int _column, GameCell[,] _cells = null, bool cleanUp = true)
        {
            if (cleanUp)
            {
                //Clean up the older cells.
                foreach (GameCell cell in gameCells)
                    cell.Cell.Dispose();
            }

            //Prevent user to create a map unusually huge.
            if (_row > MAX_ROW)
                _row = MAX_ROW;
            if (_column > MAX_COLUMN)
                _column = MAX_COLUMN;

            this.SetBounds(this.Location.X, this.Location.Y, _column * GameCell.CELL_WIDTH, _row * GameCell.CELL_HEIGHT + GameCell.CELL_HEIGHT / 2);

            //Set the new cells.
            if (_cells != null)
            {
                gameCells = _cells;

                foreach (GameCell cell in gameCells)
                    cell.ChooseColor();
            }
            else
            {
                gameCells = new GameCell[_column, _row];

                for (int i = 0; i < _row; i++)
                    for (int j = 0; j < _column; j++)
                        gameCells[j, i].Reset(j, i);
            }

            for (int i = 0; i < _row; i++)
                for (int j = 0; j < _column; j++)
                    gameCells[j, i].Cell.Parent = this;


        }

        public GameCell[,] GameCells
        {
            get { return gameCells; }
            set { gameCells = value; }
        }

        public string ToJSON()
        {
            string sJson = JsonConvert.SerializeObject(gameCells);

            return sJson;
        }

        public string ImgSrc
        {
            get { return imgSrc; }
            set { imgSrc = value; }
        }

        public void reset()
        {
            this.BackgroundImage = null;

            for (int i = 0; i < GameCells.GetLength(1); i++)
                for (int j = 0; j < GameCells.GetLength(0); j++)
                {
                    GameCells[j, i].Reset(j, i);
                }
        }

        public void ApplyImage()
        {
            if (String.IsNullOrEmpty(imgSrc))
                BackgroundImage = null;
            else
            {
                System.Drawing.Bitmap imgToStrech = new System.Drawing.Bitmap(imgSrc);
                System.Drawing.Bitmap img = new System.Drawing.Bitmap(imgToStrech, Width, Height);
                
                BackgroundImage = img;
            }
        }
        
        public void FromJSON(String _sJson)
        {
            JsonSerializerSettings settings = new JsonSerializerSettings();

            GameCell[] tmpArrayCells   = JsonConvert.DeserializeObject<GameCell[]>(_sJson);

            if (tmpArrayCells.Length > 0)
            {
                int numRow = 0;
                int numColumn = 0;

                //Calculate the number of rows and columns in the grid.
                if (tmpArrayCells[numRow].Row != tmpArrayCells[numRow + 1].Row)
                {
                    //Retrieve the number of row.
                    while (numRow < tmpArrayCells[numRow + 1].Row)
                        numRow++;

                    //Index start at 0, must increment to gain the real number of column.
                    numRow++;

                    numColumn = tmpArrayCells.Length / numRow;
                }
                else
                {
                    //Retrieve the number of row.
                    while (numColumn < tmpArrayCells[numColumn + 1].Column)
                        numColumn++;

                    //Index start at 0, must increment to gain the real number of column.
                    numColumn++;

                    numRow = tmpArrayCells.Length / numColumn;
                }

                GameCell[,] tmpGameCells = new GameCell[numColumn, numRow];

                if (tmpArrayCells[numRow].Row != tmpArrayCells[numRow + 1].Row)
                {
                    //Set all the retrieved cells in the grid.
                    for (int i = 0; i < numRow; ++i)
                        for (int j = 0; j < numColumn; ++j)
                        {
                            tmpGameCells[j, i] = tmpArrayCells[(j * numRow) + i];
                            tmpGameCells[j, i].Cell.Parent = this;
                        }
                }
                else
                {
                    //Set all the retrieved cells in the grid.
                    for (int i = 0; i < numRow; ++i)
                        for (int j = 0; j < numColumn; ++j)
                        {
                            tmpGameCells[j, i] = tmpArrayCells[(i * numColumn) + j];
                            tmpGameCells[j, i].Cell.Parent = this;
                        }
                }

                resize(numRow, numColumn, tmpGameCells);
            }
        }
    }
}
